package com.zhiyou100.shiro;

import com.zhiyou100.model.User;
import com.zhiyou100.service.LoginService;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.List;

/*
 * 继承授权域抽象类,重写 授权 , 认证的方法   先认证后授权
 */
public class MyRealm1 extends AuthorizingRealm {

    @Autowired
    LoginService loginService;

    /*
     * 授权方法 : 认证后,为当前主体授权
     *
     */

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        // 通过身份参数,获得身份即用户名
        int id = (int) principals.getPrimaryPrincipal();
        System.out.println("要授权的id是  :  "+id);
        // 根据用户名查数据库,查询对应的所有角色
        ArrayList<Integer> roleIds = loginService.findRolesById(id);
        System.out.println(roleIds);
        /*
        * 根据用户id查询用户与角色关联信息,一个用户可能有多个角色,所以返回的是集合
        *
        * 在根据角色id 去查询 角色与权限关联表
        * 在根据查到关联信息之后去查权限表
        * 最后将查到的权限信息赋值给AuthorizationInfo
        * */
        List<Integer> perIds = loginService.findPerIdByRoles(roleIds);
        List<String> per =  loginService.findPerByPerId(perIds);
        // 将角色信息,授权信息赋值给AuthorizationInfo即可
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //info.addRoles(RoleName);
        info.addStringPermissions(per);
        for (String Permission:per
             ) {
            System.out.println("当前用户的权限有  : "+Permission);

        }
        return info;
    }
    /*
     * 认证方法 : 认证当前主体
     * 参数AuthenticationToken
     * 	当登录时,即subject.login(token),就会将token赋值给此方法的参数
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        // 从令牌中得到用户名密码
        // 得到用户名
        String tel = (String) token.getPrincipal();
        // 得到密码 --> 得到是字符数组
        // 所以需要再变为字符串
        String password = new String((char[]) token.getCredentials());
        // 根据用户名查询数据库
        User user = loginService.loginBehind(tel, password);
        // 判断用户存在不存在,密码是否正确
        System.out.println("shiro返回user   :"+user);

        if (user == null) {
            throw new AuthenticationException();
        }
        // 如果都正确,将信息放入AuthenticationInfo返回
        return new SimpleAuthenticationInfo(user.getId(), user.getPassword(), getName());
    }

}
